package com.hg.util.action;

import freemarker.template.*;

import org.jdiy.util.Fs;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.*;

/**
 * 暂时没用上
 * @author Qiumingkong
 *
 */
class ActionFtlInvoker{

    public void invoke(String folder,String view,HttpServletRequest req,HttpServletResponse res) {
        this.invoke(folder,view, null,req,res);
    }

    public void invoke(String folder,String view, Map map,HttpServletRequest req,HttpServletResponse res) {
    	
    	Configuration cfg=new Configuration();
        cfg.setTemplateUpdateDelay(0);
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        cfg.setDefaultEncoding("utf-8");
        cfg.setOutputEncoding("utf-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLocale(java.util.Locale.CHINA);
        cfg.setLocalizedLookup(false);
        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        
        cfg.setServletContextForTemplateLoading(req.getSession()
				.getServletContext(), folder);		//"WEB-INF/templates/admin"
		
        try {
            cfg.setSettings(Fs.getProperties("freemarker.properties"));
        } catch (TemplateException e) {
            e.getStackTrace();
        }
    	
    	
    	Map<String, Object> root = new HashMap<String, Object>();
        for (Enumeration<String> attrs = req.getAttributeNames(); attrs.hasMoreElements(); ) {
            String key = attrs.nextElement();
            root.put(key, handleObject(req.getAttribute(key), 5));
        }
        if (map != null){
            root.putAll(handleMap(map, 5));
        }
        try {
            Template template = cfg.getTemplate(view);
            cfg.setSharedVariable("request", req);

            template.process(root, res.getWriter());
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    private Object handleObject(Object value, int depth) {
        if (value == null || (depth--) <= 0)
            return value;
        if (value instanceof List)
            return handleList((List) value, depth);
        else if (value instanceof Map)
            return handleMap((Map) value, depth);
        else if (value instanceof Object[])
            return handleArray((Object[]) value, depth);
        else
            return value;
    }

    private Map handleMap(Map map, int depth) {
        if (map == null || map.size() == 0)
            return map;
        Map<Object, Object> result = new HashMap<Object, Object>();//2.4及之前版本也不区分大小写是不正确的
        for (Object eo : map.entrySet()) {
            Map.Entry<Object, Object> e = (Map.Entry) eo;
            Object key = e.getKey();
            Object value = e.getValue();
            value = handleObject(value, depth);
            result.put(key, value);
        }
        return result;
    }

    private List handleList(List list, int depth) {
        if (list == null || list.size() == 0)
            return list;
        List result = new ArrayList(list.size());
        for (Object value : list)
            result.add(handleObject(value, depth));
        return result;
    }

    private List handleArray(Object[] array, int depth) {
        if (array == null || array.length == 0)
            return new ArrayList(0);

        List result = new ArrayList(array.length);
        for (Object anArray : array) result.add(handleObject(anArray, depth));
        return result;
    }
}
